package cn.chair.controller.admin;

import cn.chair.annotation.PublicApi;
import cn.chair.dao.OrderDao;
import cn.chair.entity.ExcelData;
import cn.chair.model.admin.*;
import cn.chair.util.ExportExcelUtils;
import cn.chair.util.SmallUtil;
import com.cfilmcloud.framework.privilege.api.model.LevelDetails;
import com.cfilmcloud.framework.privilege.api.model.UserProfile;
import life.innovation.exception.DataReadException;
import life.innovation.exception.UnauthorizedException;
import life.innovation.model.Page;
import life.innovation.model.PageList;
import life.innovation.util.DateUtil;
import life.innovation.util.PagerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping(value = "order")
@RestController
public class PurchaseOrderController {

    @Autowired
    @Lazy
    private OrderDao orderDao;

    /**
     * 订单管理
     *
     * @param orderNo
     * @param startDate
     * @param endDate
     * @param orderStatus
     * @param chairCode
     * @param merchantName
     * @param page
     * @param countPerPage
     * @return
     * @throws DataReadException
     */
    @GetMapping(value = "getOrders")
    public PurchaseOrderResp getOrders(@RequestParam(required = false) String orderNo,
                                       @RequestParam(required = false) String transNo,
                                       @RequestParam(required = false) String startDate,
                                       @RequestParam(required = false) String endDate,
                                       @RequestParam(required = false) Integer orderStatus,
                                       @RequestParam(required = false) String chairCode,
                                       @RequestParam(required = false) String merchantName,
                                       @RequestParam(required = false) Integer paySource,
                                       @RequestParam(required = false, defaultValue = "1") int page,
                                       @RequestParam(required = false, defaultValue = "20") int countPerPage, UserProfile userProfile) throws DataReadException {

        LevelDetails levelDetails = userProfile.getLevelDetails();

        List<Integer> storeId = null;
        if(!SmallUtil.isEmpty(levelDetails.getStoreId())){
            List<String> stores = Arrays.asList(levelDetails.getStoreId().split(","));
            storeId = stores.stream().map(Integer::parseInt).collect(Collectors.toList());
        }

        PurchaseOrderResp orderResp = new PurchaseOrderResp();

        PageList<PurchaseOrderResp.OrderList> list = orderDao.getOrderList(transNo, orderNo, startDate, endDate, orderStatus, chairCode, merchantName,paySource, page, countPerPage,storeId);

        orderResp.setPagination(list.getPagination());
        orderResp.setList(list.getList());


        return orderResp;
    }

    /**
     * 消费订单汇总(除充值摩豆)
     * @param orderNo
     * @param startDate
     * @param endDate
     * @param orderStatus
     * @param chairCode
     * @param merchantName
     * @param paySource
     * @return
     * @throws DataReadException
     */
    @GetMapping(value="getOrderSummary")
    public List<PurchaseOrderSummaryResp> getOrderSummary(@RequestParam(required = false) String orderNo,
                                                          @RequestParam(required = false) String startDate,
                                                          @RequestParam(required = false) String endDate,
                                                          @RequestParam(required = false) Integer orderStatus,
                                                          @RequestParam(required = false) String chairCode,
                                                          @RequestParam(required = false) String merchantName,
                                                          @RequestParam(required = false) Integer paySource,UserProfile userProfile) throws DataReadException {

        LevelDetails levelDetails = userProfile.getLevelDetails();

        List<Integer> storeId = null;
        if(!SmallUtil.isEmpty(levelDetails.getStoreId())){
            List<String> stores = Arrays.asList(levelDetails.getStoreId().split(","));
            storeId = stores.stream().map(Integer::parseInt).collect(Collectors.toList());
        }

        List<PurchaseOrderSummaryResp> list = orderDao.getOrderSummary(orderNo,startDate,endDate,orderStatus,chairCode,merchantName,paySource,storeId);

        Map<Integer,Object> maps = new HashMap<>();
        if(list != null&&list.size() > 0){
            for(PurchaseOrderSummaryResp resp : list){
                if(maps.containsKey(resp.getStatus())){
                  PurchaseOrderSummaryResp existResp = (PurchaseOrderSummaryResp) maps.get(resp.getStatus());

                    existResp.setOrderCount(existResp.getOrderCount()+resp.getOrderCount());
                    existResp.setOrderAmount(existResp.getOrderAmount()+resp.getOrderAmount());
                    if(resp.getPaySource() == 0){
                      existResp.setAmount(existResp.getAmount()+resp.getAmount());
                    }else{
                        existResp.setTokenAmount(existResp.getTokenAmount()+resp.getAmount());
                    }


                }else{
                    PurchaseOrderSummaryResp orderResp = new PurchaseOrderSummaryResp();

                    orderResp.setOrderCount(resp.getOrderCount());
                    orderResp.setOrderAmount(resp.getOrderAmount());
                    orderResp.setStatus(resp.getStatus());
                    if(resp.getPaySource() == 0){
                        orderResp.setAmount(resp.getAmount());
                    }else{
                        orderResp.setTokenAmount(resp.getAmount());
                    }

                    maps.put(resp.getStatus(),orderResp);
                }
            }
        }

        List<PurchaseOrderSummaryResp> orderList = new ArrayList<>();
        if(maps != null&&maps.size() > 0){
            for (Map.Entry<Integer, Object> entry : maps.entrySet()) {
                orderList.add((PurchaseOrderSummaryResp) entry.getValue());
            }

        }

        return orderList;

    }

    /**
     * 导出订单信息
     *
     * @param response
     * @param orderNo
     * @param startDate
     * @param endDate
     * @param orderStatus
     * @param chairCode
     * @param merchantName
     * @throws Exception
     */
    @GetMapping(value = "getExcelOrders")
    public void ExcelOrders(HttpServletResponse response, @RequestParam(required = false) String orderNo,
                            @RequestParam(required = false) String startDate,
                            @RequestParam(required = false) String endDate,
                            @RequestParam(required = false) Integer orderStatus,
                            @RequestParam(required = false) String chairCode,
                            @RequestParam(required = false) String merchantName,
                            @RequestParam(required = false) Integer paySource,UserProfile userProfile) throws Exception {

        LevelDetails levelDetails = userProfile.getLevelDetails();

        List<Integer> storeId = null;
        if(!SmallUtil.isEmpty(levelDetails.getStoreId())){
            List<String> stores = Arrays.asList(levelDetails.getStoreId().split(","));
            storeId = stores.stream().map(Integer::parseInt).collect(Collectors.toList());
        }
        List<PurchaseOrderResp.OrderList> list = orderDao.getOrderExcelList(orderNo, startDate, endDate, orderStatus, chairCode, merchantName,paySource,storeId);


        ExcelData data = new ExcelData();
        List<String> titles = new ArrayList<>();
        titles.add("摩摩乐订单号");
        titles.add("微信支付订单号");
        titles.add("影院ID");
        titles.add("设备ID");
        titles.add("支付金额");
        titles.add("用户ID");
        titles.add("用户手机号");
        titles.add("设备所在影院");
        titles.add("订单金额");
        titles.add("下单时间");
        titles.add("订单状态");
        titles.add("订单类型");

        data.setTitles(titles);

        List<List<Object>> rows = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (PurchaseOrderResp.OrderList orderList : list) {
                List<Object> row = new ArrayList<>();
                row.add(orderList.getOrderNo());
                row.add(orderList.getTransNo());
                row.add(orderList.getMerchantId());
                row.add(orderList.getChairCode());
                row.add(orderList.getAmount());
                row.add(orderList.getUserId());
                row.add(orderList.getMobile());
                row.add(orderList.getMerchantName());
                row.add(orderList.getOrderAmount());
                row.add(DateUtil.valueOf(orderList.getOrderTime()));

                int status = orderList.getOrderStatus();

                if (status == 1) {
                    row.add("已支付");
                }
                if (status == 2) {
                    row.add("未支付");
                }

                int source = orderList.getPaySource();
                if (source == 0) {
                    row.add("微信支付");
                }
                if (source == 1) {
                    row.add("用户充值");
                }
                if (source == 2) {
                    row.add("摩豆支付");
                }
                rows.add(row);
            }

            data.setRows(rows);
            data.setName("订单报表");
        }


        String filename = "订单报表.xlsx";
        ExportExcelUtils.exportExcel(response, filename, data);
    }

    /**
     * 门店结算报表
     *
     * @param merchantId
     * @param merchantName
     * @param startDate
     * @param endDate
     * @param regionId
     * @param page
     * @param countPerPage
     * @return
     * @throws DataReadException
     */
    @GetMapping(value = "getMerchantOrders")
    public MerchantOrderResp getMerchantOrders(@RequestParam(required = false) Integer merchantId,
                                               @RequestParam(required = false) String merchantName,
                                               @RequestParam(required = false) String startDate,
                                               @RequestParam(required = false) String endDate,
                                               @RequestParam(required = false) Integer regionId,
                                               @RequestParam(required = false, defaultValue = "1") int page,
                                               @RequestParam(required = false, defaultValue = "20") int countPerPage,UserProfile userProfile) throws DataReadException {

        LevelDetails levelDetails = userProfile.getLevelDetails();

        List<Integer> storeId = null;
        if(!SmallUtil.isEmpty(levelDetails.getStoreId())){
            List<String> stores = Arrays.asList(levelDetails.getStoreId().split(","));
            storeId = stores.stream().map(Integer::parseInt).collect(Collectors.toList());
        }
        MerchantOrderResp resp = new MerchantOrderResp();

        List<MerchantOrderResp.MerchantOrderList> orderList = dealOrderData(merchantId, merchantName, startDate, endDate, regionId,storeId);
        Page pagination = PagerUtil.process(page, countPerPage, orderList.size());
        resp.setPagination(pagination);
        resp.setList(orderList);
        return resp;

    }


    /**
     * 门店结算报表导出
     *
     * @param merchantId
     * @param merchantName
     * @param startDate
     * @param endDate
     * @param regionId
     * @throws DataReadException
     */
    @GetMapping(value = "getExcelMerchantOrders")
    public void ExcelMerchantOrders(HttpServletResponse response, @RequestParam(required = false) Integer merchantId,
                                    @RequestParam(required = false) String merchantName,
                                    @RequestParam(required = false) String startDate,
                                    @RequestParam(required = false) String endDate,
                                    @RequestParam(required = false) Integer regionId,UserProfile userProfile) throws Exception {
        LevelDetails levelDetails = userProfile.getLevelDetails();

        List<Integer> storeId = null;
        if(!SmallUtil.isEmpty(levelDetails.getStoreId())){
            List<String> stores = Arrays.asList(levelDetails.getStoreId().split(","));
            storeId = stores.stream().map(Integer::parseInt).collect(Collectors.toList());
        }
        List<MerchantOrderResp.MerchantOrderList> orderList = dealOrderData(merchantId, merchantName, startDate, endDate, regionId,storeId);

        ExcelData data = new ExcelData();
        List<String> titles = new ArrayList<>();
        titles.add("影院ID");
        titles.add("影院名称");
        titles.add("订单数量");
        titles.add("实收金额");
        titles.add("魔豆金额");

        data.setTitles(titles);

        List<List<Object>> rows = new ArrayList<>();
        if (orderList != null && orderList.size() > 0) {
            for (MerchantOrderResp.MerchantOrderList merchantOrderList : orderList) {
                List<Object> row = new ArrayList<>();
                row.add(merchantOrderList.getMerchantId());
                row.add(merchantOrderList.getMerchantName());
                row.add(merchantOrderList.getOrderCount());
                row.add(merchantOrderList.getPayAmount());
                row.add(merchantOrderList.getTokenAmount());

                rows.add(row);
            }
            data.setRows(rows);
            data.setName("门店结算报表");
        }
        String filename = "门店结算报表.xlsx";
        ExportExcelUtils.exportExcel(response, filename, data);

    }

    /**
     * 门店结算报表数据处理
     *
     * @param merchantId
     * @param merchantName
     * @param startDate
     * @param endDate
     * @param regionId
     * @return
     * @throws DataReadException
     */
    public List<MerchantOrderResp.MerchantOrderList> dealOrderData(Integer merchantId, String merchantName, String startDate, String endDate, Integer regionId,List<Integer> storeId) throws DataReadException {
        List<MerchantOrderResp.MerchantOrderList> list = orderDao.getOrders(merchantId, merchantName, startDate, endDate, regionId,storeId);

        Map<Integer, Object> maps = new HashMap<>();
        if (list.size() >= 0 && list != null) {
            for (MerchantOrderResp.MerchantOrderList merchantOrderList : list) {
                if (maps.containsKey(merchantOrderList.getMerchantId())) {
                    MerchantOrderResp.MerchantOrderList exitOrder = (MerchantOrderResp.MerchantOrderList) maps.get(merchantOrderList.getMerchantId());

                    int orderCount = exitOrder.getOrderCount();
                    exitOrder.setOrderCount(orderCount + merchantOrderList.getOrderCount());
                    if (merchantOrderList.getPaySource() == 0) {
                        exitOrder.setPayAmount(merchantOrderList.getAmount());
                    } else {
                        exitOrder.setTokenAmount(merchantOrderList.getAmount());
                    }

                } else {
                    MerchantOrderResp.MerchantOrderList order = new MerchantOrderResp.MerchantOrderList();
                    if (merchantOrderList.getPaySource() == 0) {
                        order.setMerchantId(merchantOrderList.getMerchantId());
                        order.setMerchantName(merchantOrderList.getMerchantName());
                        order.setOrderCount(merchantOrderList.getOrderCount());
                        order.setPayAmount(merchantOrderList.getAmount());
                    } else {
                        order.setMerchantId(merchantOrderList.getMerchantId());
                        order.setMerchantName(merchantOrderList.getMerchantName());
                        order.setOrderCount(merchantOrderList.getOrderCount());
                        order.setTokenAmount(merchantOrderList.getAmount());
                    }

                    maps.put(merchantOrderList.getMerchantId(), order);

                }

            }
        }

        List<MerchantOrderResp.MerchantOrderList> orderList = new ArrayList<>();
        for (Map.Entry<Integer, Object> entry : maps.entrySet()) {
            orderList.add((MerchantOrderResp.MerchantOrderList) entry.getValue());
        }

        return orderList;
    }


    /**
     * 储值汇总
     *
     * @param startDate
     * @param endDate
     * @return
     * @throws DataReadException
     */
    @GetMapping(value = "getRechargeOrder")
    public RechargeOrderResp get(@RequestParam(required = false) String startDate,
                                 @RequestParam(required = false) String endDate) throws DataReadException {

        RechargeOrderResp resp = new RechargeOrderResp();

        List<RechargeOrderResp> list = orderDao.getRechargeOrder(startDate, endDate);

        if (list != null || list.size() > 0) {
            resp = list.get(0);
        }
        return resp;
    }

    /**
     * 储值订单列表详情
     *
     * @param startDate
     * @param endDate
     * @param page
     * @param countPerPage
     * @return
     * @throws DataReadException
     */
    @GetMapping(value = "getRechargeOrderList")
    public RechargeOrderListResp get(@RequestParam(required = false) String startDate,
                                     @RequestParam(required = false) String endDate,
                                     @RequestParam(required = false, defaultValue = "1") int page,
                                     @RequestParam(required = false, defaultValue = "20") int countPerPage) throws DataReadException {
        RechargeOrderListResp resp = new RechargeOrderListResp();

        PageList<RechargeOrderListResp.RechargeOrderList> list = orderDao.getRechargeOrderList(startDate, endDate, page, countPerPage);

        resp.setPagination(list.getPagination());
        resp.setList(list.getList());
        return resp;
    }

    /**
     * 储值订单报表导出
     *
     * @param response
     * @param startDate
     * @param endDate
     * @throws Exception
     */
    @GetMapping(value = "getExcelRechargeOrderList")
    public void getExcelRechargeOrderList(HttpServletResponse response,
                                          @RequestParam(required = false) String startDate,
                                          @RequestParam(required = false) String endDate) throws Exception {

        List<RechargeOrderListResp.RechargeOrderList> list = orderDao.getExcelRechargeOrderList(startDate, endDate);

        ExcelData data = new ExcelData();
        List<String> titles = new ArrayList<>();
        titles.add("摩摩乐订单号");
        titles.add("微信支付订单号");
        titles.add("实际支付金额");
        titles.add("用户ID");
        titles.add("用户手机号");
        titles.add("摩豆数量");
        titles.add("订单金额");
        titles.add("下单时间");
        titles.add("订单状态");

        data.setTitles(titles);

        List<List<Object>> rows = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (RechargeOrderListResp.RechargeOrderList rechargeOrderList : list) {
                List<Object> row = new ArrayList<>();
                row.add(rechargeOrderList.getOrderNo());
                row.add(rechargeOrderList.getTransNo());
                row.add(rechargeOrderList.getAmount());
                row.add(rechargeOrderList.getUserId());
                row.add(rechargeOrderList.getMobile());
                row.add(rechargeOrderList.getToken());
                row.add(rechargeOrderList.getOrderAmount());
                row.add(DateUtil.valueOf(rechargeOrderList.getOrderTime()));
                row.add("订单成功");

                rows.add(row);
            }
            data.setRows(rows);
        }

        data.setName("储值订单报表");

        String filename = "储值订单报表.xlsx";
        ExportExcelUtils.exportExcel(response, filename, data);

    }
}